package com.offcn.seckill.thread;

import com.alibaba.fastjson.JSON;
import com.offcn.seckill.dao.SeckillGoodsMapper;
import com.offcn.seckill.entity.SeckillStatus;
import com.offcn.seckill.pojo.SeckillGoods;
import com.offcn.seckill.pojo.SeckillOrder;
import com.offcn.utils.IdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.concurrent.Future;

@Component
public class MultiThreadCreateOrder {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired(required = false)
    private SeckillGoodsMapper seckillGoodsMapper;

    /**
     * 一般情况下，多线程方法是没有返回值的
     */
    @Async // 多线程执行方法
    public Future<Boolean> create(){
//        System.out.println("多线程的方法开始执行");
//        try {
//            Thread.sleep(10000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        System.out.println("多线程的方法执行结束");

        String seckillStatusJSON = stringRedisTemplate.boundListOps("seckillOrderQueue").rightPop();
        SeckillStatus seckillStatus = JSON.parseObject(seckillStatusJSON, SeckillStatus.class);

        String time = seckillStatus.getTime();
        String id = seckillStatus.getGoodsId().toString();
        String username = seckillStatus.getUsername();

        String seckillGoodsJson = (String)stringRedisTemplate.boundHashOps("seckillGoods_" + time).get(id);
        SeckillGoods seckillGoods = JSON.parseObject(seckillGoodsJson, SeckillGoods.class);

        if (seckillGoods == null){
//            throw new RuntimeException("商品已售罄");
            return new AsyncResult<>(false);
        }

        String idStr = stringRedisTemplate.boundListOps("seckillGoodsCountList_" + seckillGoods.getId()).rightPop();
        if (idStr == null) {
            // 商品售罄
//            throw new RuntimeException("商品已售罄");
            return new AsyncResult<>(false);
        }

//        if (seckillGoods == null || seckillGoods.getStockCount() <= 0){
//            // 商品售罄
//            throw new RuntimeException("商品已售罄");
//        }
        // 创建订单
        SeckillOrder seckillOrder = new SeckillOrder();
        long orderId = new IdWorker(1, 3).nextId();
        seckillOrder.setId(orderId);
        seckillOrder.setSeckillId(Long.parseLong(id));
        // 每次抢购一件商品，因此商品的价格就是支付金额
        seckillOrder.setMoney(seckillGoods.getCostPrice());
        seckillOrder.setUserId(username);
        seckillOrder.setCreateTime(new Date());
        seckillOrder.setStatus("0"); // 未支付
        // 订单数据添加到redis
        String seckillOrderJSON = JSON.toJSONString(seckillOrder);
        stringRedisTemplate.boundHashOps("seckillOrder").put(username,seckillOrderJSON);

        // 订单抢购的数据完成数据补全
        seckillStatus.setStatus(2); // 待支付
        seckillStatus.setOrderId(orderId);
        seckillStatus.setMoney(seckillGoods.getCostPrice());
        stringRedisTemplate.boundHashOps("userQueueStatus").put(username,JSON.toJSONString(seckillStatus));

        // 减库存
//        seckillGoods.setStockCount(seckillGoods.getStockCount() - 1);
//        if (seckillGoods.getStockCount() <= 0){
//            seckillGoodsMapper.updateById(seckillGoods);
//            // 清除redis中的商品的数据
//            stringRedisTemplate.boundHashOps("seckillGoods_" + time).delete(id);
//        }else{
//            stringRedisTemplate.boundHashOps("seckillGoods_" + time).put(id,JSON.toJSONString(seckillGoods));
//        }

        // 减库存 用于计算实际库存
        Long stockCount = stringRedisTemplate.boundHashOps("SeckillGoodsCount").increment(id, -1);
        seckillGoods.setStockCount(stockCount.intValue());

        if (stockCount == 0) {
            seckillGoodsMapper.updateById(seckillGoods);
            // 清除redis中的商品的数据
            stringRedisTemplate.boundHashOps("seckillGoods_" + time).delete(id);
            // 清除 计数器
            stringRedisTemplate.boundHashOps("SeckillGoodsCount").delete(id);
        }else if(stockCount > 0){
            stringRedisTemplate.boundHashOps("seckillGoods_" + time).put(id,JSON.toJSONString(seckillGoods));
        }else {
//            throw new RuntimeException("商品售罄");
            return new AsyncResult<>(false);
        }
        return new AsyncResult<>(true);

    }
}
